local L = LibStub("AceLocale-3.0"):GetLocale("AzCastBarOptions")
if (select(2,UnitClass("player")) ~= "SHAMAN") then
	return;
end

local GetTime = GetTime;
local FormatTime = AzCastBar.FormatTime;

local b = AzCastBar.CreateBar("Button");
local UpdateTotemBars;
local totems = {};
local sentry = GetSpellInfo(6495);

-- Extra Options
local extraOptions = {
	{
		[0] = L["Additional"],
		{ type = "Color", var = "colNormal", default = { 0.4, 0.6, 0.8, 1 }, label = L["Totem Bar Color"] },
	},
};

--------------------------------------------------------------------------------------------------------
--                                               Events                                               --
--------------------------------------------------------------------------------------------------------

-- OnUpdate
local function OnUpdate(self,elapsed)
	local totem = self.totem;
	-- Normal Progression
	if (not self.fadeTime) then
		self.timeLeft = max(0,totem.endTime - GetTime());
		self.status:SetValue(self.timeLeft);
		self.time:SetText(FormatTime(self.timeLeft)..(b.cfg.showTotalTime and " / "..FormatTime(totem.duration) or ""));
		if (self.timeLeft == 0) then
			self.fadeTime = b.cfg.fadeTime
		end
	-- FadeOut
	elseif (self.fadeElapsed <= self.fadeTime) then
		self.fadeElapsed = (self.fadeElapsed + elapsed);
		self:SetAlpha(b.cfg.alpha - self.fadeElapsed / self.fadeTime * b.cfg.alpha);
	else
		tremove(totems,self.index);
		UpdateTotemBars();
	end
end

-- OnClick
local function OnClick(self,button,down)
	if (button == "RightButton") then
		DestroyTotem(self.totem.id);
	elseif (self.totem.name == sentry) then
		CancelUnitBuff("player",sentry);
	end
end

-- OnEvent
local function OnEvent(self,event,...)
	wipe(totems);
	local haveTotem, totemName, startTime, duration, texture;
	for i = 1, MAX_TOTEMS do
		haveTotem, totemName, startTime, duration, texture = GetTotemInfo(i);
		if (totemName and totemName ~= "") then
			tinsert(totems,{ id = i, name = totemName, endTime = startTime + duration, duration = duration, texture = texture });
		end
	end
	UpdateTotemBars();
end

--------------------------------------------------------------------------------------------------------
--                                                Code                                                --
--------------------------------------------------------------------------------------------------------

-- ConfigureBar
local function ConfigureBar(bar,id)
	bar:EnableMouse(1);
	bar:RegisterForClicks("LeftButtonUp","RightButtonUp");
	bar:SetScript("OnUpdate",OnUpdate);
	bar:SetScript("OnClick",OnClick);
	tinsert(b.bars,bar);
	AzCastBar.ApplyBarSettingsSpecific(b,id);
	return bar;
end

-- UpdateBars
UpdateTotemBars = function()
	local bar;
	-- Loop Rolls
	for index, table in ipairs(totems) do
		bar = b.bars[index] or ConfigureBar(AzCastBar.CreateBar("Button"),index);
		bar.status:SetMinMaxValues(0,table.duration);
		bar.status:SetStatusBarColor(unpack(b.cfg.colNormal));
		bar.name:SetText(table.name);
		bar.icon:SetTexture(table.texture);
		bar.totem = table;
		bar.index = index;
		bar.fadeTime = nil;
		bar.fadeElapsed = 0;
		bar:SetAlpha(b.cfg.alpha);
		bar:Show();
	end
	-- Hide Remaining
	for i = #totems + 1, #b.bars do
		b.bars[i]:Hide();
	end
end

--------------------------------------------------------------------------------------------------------
--                                              Finalize                                              --
--------------------------------------------------------------------------------------------------------

-- OnConfigChanged
function b:OnConfigChanged(cfg,barId)
	if (barId ~= 1) then
		return;
	elseif (cfg.enabled) then
		self:RegisterEvent("PLAYER_TOTEM_UPDATE");
		self:RegisterEvent("PLAYER_ENTERING_WORLD");
		OnEvent(self);
	else
		self:UnregisterAllEvents();
		wipe(totems);
		UpdateTotemBars();
	end
end

-- Init AzCastBar Entry
b.token = L["Totems"];
b.options = extraOptions;
b.bars = {};
b:ClearAllPoints();
b:SetPoint("CENTER");
b:SetScript("OnEvent",OnEvent);
ConfigureBar(b,1);
tinsert(AzCastBar.frames,b);